package k8s_ui

import (
	"context"
	"encoding/json"
	"errors"
	"github.com/wonderivan/logger"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var Secret secret

type secret struct{}

// 定义secretCreate结构体，用于创建secret需要的参数属性的定义
type SecretCreate struct {
	Name       string            `json:"secret_name"`
	Namespace  string            `json:"namespace"`
	Data       map[string][]byte `json:"data"`
	StringData map[string]string `json:"stringdata"`
	Type       string            `json:"type"`
}

// 定义secretNp类型，用于返回namespace中secret的数量
type SecretNp struct {
	Namespace string `json:"secretname"`
	SecretNum int    `json:"secret_num"`
}

type SecretResp struct {
	Items []corev1.Secret `json:"items"`
	Total int             `json:"total"`
}

// 查询secret
func (p *secret) GetSecrets(filterName, namespace string, limit, page int) (secretResp *SecretResp, err error) {
	//获取secretList类型的secret列表
	secretList, err :=
		K8s.ClientSet.CoreV1().Secrets(namespace).List(context.TODO(),
			metav1.ListOptions{})
	aa := secretList
	print(aa)
	if err != nil {
		logger.Error(errors.New("获取secret列表失败, " + err.Error()))
		return nil, errors.New("获取secret列表失败, " + err.Error())
	}

	//将secretList中的secret列表(Items)，放进dataselector对象中，进行排序
	selectableData := &DataSelector{
		GenericDataList: p.toCells(secretList.Items),
		DataSelect: &DataSelectQuery{
			Filter: &FilterQuery{Name: filterName},
			Paginate: &PaginateQuery{
				Limit: limit,
				Page:  page,
			},
		},
	}
	filtered := selectableData.Filter()
	total := len(filtered.GenericDataList)
	data := filtered.Sort().Paginate()
	//将[]DataCell类型的secret列表转为secret列表
	secrets := p.fromCells(data.GenericDataList)
	return &SecretResp{
		Items: secrets,
		Total: total,
	}, nil
}

// toCells方法用于将secret类型转成DataCell类型
func (*secret) toCells(std []corev1.Secret) []DataCell {
	cells := make([]DataCell, len(std))
	for i := range std {
		//std[i]原生pod类型 -> podCell -> DataCell
		cells[i] = secretCell(std[i])
	}
	return cells
}

// fromCells方法用于将DataCell类型转成secret类型
func (*secret) fromCells(cells []DataCell) []corev1.Secret {
	secrets := make([]corev1.Secret, len(cells))
	for i := range cells {
		//cells[i] DataCell接口类型 -> podCell -> 原生pod类型
		secrets[i] = corev1.Secret(cells[i].(secretCell))
	}
	return secrets
}

// 获取secret详情
func (*secret) GetSecretDetail(secretName, namespace string) (secret *corev1.Secret, err error) {
	secret, err = K8s.ClientSet.CoreV1().Secrets(namespace).Get(context.TODO(), secretName, metav1.GetOptions{})
	if err != nil {
		logger.Error(errors.New("获取secret详情失败, " + err.Error()))
		return nil, errors.New("获取secret详情失败, " + err.Error())
	}
	return secret, nil
}

// 创建secret接收secretCreate对象
func (*secret) CreateSecret(data *SecretCreate) (err error) {
	//将data中的数据组装成corev1.secret对象
	secret := &corev1.Secret{
		//ObjectMeta中定义资源名、命名空间以及标签
		ObjectMeta: metav1.ObjectMeta{
			Name:      data.Name,
			Namespace: data.Namespace,
		},
		// Type在前段写死下拉选项
		Type:       corev1.SecretType(data.Type),
		StringData: data.StringData,
		Data:       data.Data,
	}
	//创建secret
	_, err = K8s.ClientSet.CoreV1().Secrets(data.Namespace).Create(context.TODO(), secret, metav1.CreateOptions{})
	if err != nil {
		logger.Error(errors.New("创建secret失败, " + err.Error()))
		return errors.New("创建secret失败, " + err.Error())
	}
	return nil
}

// 删除secret
func (*secret) DeleteSecret(secretName, namespace string) (err error) {
	err = K8s.ClientSet.CoreV1().Secrets(namespace).Delete(context.TODO(),
		secretName, metav1.DeleteOptions{})
	if err != nil {
		logger.Error(errors.New("删除secret失败, " + err.Error()))
		return errors.New("删除secret失败, " + err.Error())
	}
	return nil
}

// 更新secret
func (*secret) UpdateSecret(namespace, content string) (err error) {
	var secret = &corev1.Secret{}
	err = json.Unmarshal([]byte(content), secret)
	if err != nil {
		logger.Error(errors.New("反序列化失败, " + err.Error()))
		return errors.New("反序列化失败, " + err.Error())
	}
	_, err = K8s.ClientSet.CoreV1().Secrets(namespace).Update(context.TODO(),
		secret, metav1.UpdateOptions{})
	if err != nil {
		logger.Error(errors.New("更新secret失败, " + err.Error()))
		return errors.New("更新secret失败, " + err.Error())
	}
	return nil
}

// 获取每个namespace的secret数量
func (*secret) GetSecretNumPerNp() (secretNps []*SecretNp, err error) {
	namespaceList, err := K8s.ClientSet.CoreV1().Namespaces().List(context.TODO(),
		metav1.ListOptions{})
	if err != nil {
		return nil, err
	}
	for _, namespace := range namespaceList.Items {
		secretList, err :=
			K8s.ClientSet.CoreV1().Secrets(namespace.Name).List(context.TODO(),
				metav1.ListOptions{})
		if err != nil {
			return nil, err
		}
		secretNp := &SecretNp{
			Namespace: namespace.Name,
			SecretNum: len(secretList.Items),
		}
		secretNps = append(secretNps, secretNp)
	}
	return secretNps, nil
}
